package com.whfc.ms.api.sys.controller;

import com.alibaba.fastjson.JSONObject;
import com.whfc.common.result.Result;
import com.whfc.common.result.ResultUtil;
import com.whfc.common.util.SessionAttr;
import com.whfc.entity.dto.login.LoginUserDTO;
import com.whfc.entity.dto.login.MsUserLogin;
import com.whfc.entity.dto.login.MsWxLogin;
import com.whfc.entity.dto.login.ThirdLoginToken;
import com.whfc.fuum.dto.WxUserToken;
import com.whfc.fuum.entity.SysUser;
import com.whfc.fuum.entity.WxUser;
import com.whfc.ms.api.sys.service.MsLoginService;
import com.whfc.ms.redis.UserSessionRedisDao;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.session.SessionRepository;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;

/**
 * 系统登录
 */
@RestController
@RequestMapping("/ms/api")
public class  MsLoginController {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private MsLoginService msLoginService;

    @Autowired
    private UserSessionRedisDao userSessionRedisDao;

    @Autowired
    private SessionRepository sessionRepository;

    /**
     * 登录
     *
     * @param user
     * @return
     */
    @PostMapping(value = "/login")
    public Result userLogin(@RequestBody @Validated MsUserLogin user, HttpServletRequest request) {
        logger.info("用户登录,username:{},password:{}", user.getUsername(), "*******");
        UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(), user.getPassword());
        Subject currentUser = SecurityUtils.getSubject();
        currentUser.login(token);

        //获取登录用户
        SysUser loginUser = (SysUser) SecurityUtils.getSubject().getSession().getAttribute(SessionAttr.MS_USER);

        //登录互斥
        String sessionId = request.getSession().getId();
        userSessionRedisDao.setSessionId(loginUser.getId(), sessionId);

        //返回信息
        LoginUserDTO loginUserDTO = this.from(loginUser);
        loginUserDTO.setLoginMethod(SessionAttr.USERPASS_LOGIN);
        return ResultUtil.success(loginUserDTO);

    }

    @PostMapping(value = "/wxlogin")
    public Result wxLogin(@RequestBody @Validated MsWxLogin loginParam, HttpServletRequest request) {
        logger.info("微信登录,code:{}", loginParam.getCode());

        Subject currentUser = SecurityUtils.getSubject();
        WxUser wxUser = (WxUser) currentUser.getSession().getAttribute(SessionAttr.WXWEB_USER);
        if (wxUser == null) {
            //通过code生成微信用户
            wxUser = msLoginService.getWxUserByCode(loginParam.getCode());
        }

        //授权登录
        WxUserToken token = new WxUserToken();
        token.setWxUser(wxUser);
        currentUser.login(token);

        //获取登录用户
        SysUser loginUser = (SysUser) SecurityUtils.getSubject().getSession().getAttribute(SessionAttr.MS_USER);

        //登录互斥
        String sessionId = request.getSession().getId();
        userSessionRedisDao.setSessionId(loginUser.getId(), sessionId);

        //返回信息
        LoginUserDTO loginUserDTO = this.from(loginUser);
        loginUserDTO.setLoginMethod(SessionAttr.WX_LOGIN);
        return ResultUtil.success(loginUserDTO);
    }

    @PostMapping(value = "/third-login")
    public Result thirdLogin(@RequestBody String param, HttpServletRequest request) {
        logger.info("第三方系统登录,param:{}", param);
        String code = JSONObject.parseObject(param).getString("code");
        Subject currentUser = SecurityUtils.getSubject();
        ThirdLoginToken thirdLoginToken = new ThirdLoginToken();
        thirdLoginToken.setCode(code);
        currentUser.login(thirdLoginToken);

        //获取登录用户
        SysUser loginUser = (SysUser) SecurityUtils.getSubject().getSession().getAttribute(SessionAttr.MS_USER);

        //返回信息
        LoginUserDTO loginUserDTO = this.from(loginUser);
        loginUserDTO.setLoginMethod(SessionAttr.THIRD_LOGIN);
        return ResultUtil.success(loginUserDTO);
    }


    @RequestMapping(value = "logout", method = RequestMethod.POST)
    public Result logout() {
        logger.info("退出登录");
        try {
            // 退出
            SecurityUtils.getSubject().logout();
        } catch (Exception e) {
            logger.warn("退出登录异常.", e);
        }
        return ResultUtil.success();

    }

    @RequestMapping("kick/{userId}")
    public Result kickUser(@PathVariable("userId") Integer userId) {
        logger.info("剔除在线用户,userId:{}", userId);
        String sessionId = userSessionRedisDao.getSessionId(userId);
        sessionRepository.deleteById(sessionId);
        return ResultUtil.success();
    }


    /**
     * 数据对象转换
     *
     * @param loginUser
     * @return
     */
    private LoginUserDTO from(SysUser loginUser) {
        LoginUserDTO loginUserDTO = new LoginUserDTO();
        loginUserDTO.setUserId(loginUser.getId());
        loginUserDTO.setUserName(loginUser.getUsername());
        loginUserDTO.setNickname(loginUser.getNickname());
        loginUserDTO.setPhone(loginUser.getPhone());
        return loginUserDTO;
    }
}